﻿#pragma once

#ifndef BRIDGEANALYSIS_DEFINES_H
#define BRIDGEANALYSIS_DEFINES_H

#include <iostream>
#include <fstream>
#include <sstream>
#include <exception>
#include <boost/locale.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/thread/thread.hpp>
#include <boost/log/trivial.hpp>
#include <boost/json.hpp>
#include <string>
#include <map>
#include <unordered_map>
#include <mutex>
#include <cstdint>
#include <cstddef>
#include <filesystem>
#include <cinttypes>
#include <cmath>
#include <algorithm>
#include <queue>
#include <boost/filesystem.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/attributes.hpp>
#include <boost/log/sinks/text_file_backend.hpp>
#include <boost/log/sinks/text_ostream_backend.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/attributes/current_process_id.hpp>
#include <boost/log/attributes/current_thread_id.hpp>
#include <boost/log/attributes/current_process_name.hpp>
#include <boost/log/attributes/clock.hpp>
#include <boost/log/utility/setup/settings.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/utility/manipulators/to_log.hpp>
#include <boost/log/utility/setup/formatter_parser.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/exception/all.hpp> // Boost异常处理（含error_info）
#include <sw/redis++/redis++.h>
#include <boost/format.hpp>
#include "uuid_generator.h"

using namespace std::chrono_literals;
#if false
#include <boost/stacktrace.hpp> // 核心堆栈跟踪功能
typedef boost::error_info<struct tag_stacktrace, boost::stacktrace::stacktrace> traced;
#endif

#ifdef _WIN32

#include <windows.h>

#define LOCK_TYPE CRITICAL_SECTION
#define LOCK(lock) EnterCriticalSection(&(lock))
#define UNLOCK(lock) LeaveCriticalSection(&(lock))
#define INIT_LOCK(lock) InitializeCriticalSection(&(lock))
#define DESTROY_LOCK(lock) DeleteCriticalSection(&(lock))

#define DYNLIB_HANDLE HINSTANCE
#define DYNLIB_LOAD(libname) LoadLibraryA(libname)
#define DYNLIB_GETSYM(handle, symbol) GetProcAddress(handle, symbol)
#define DYNLIB_FREE(handle) FreeLibrary(handle)
#define DYNLIB_ERROR() "DYNLIB_ERROR"

#else

#include <unistd.h>
#include <limits.h>
#include <dlfcn.h>
#define CALLBACK
#define WINAPI
#define TRUE 1
#define FALSE 0
typedef uint16_t WORD;
typedef uint32_t DWORD;
typedef void *LPVOID;
typedef void *PVOID;
typedef int32_t *LPINT;
typedef uint8_t *LPBYTE;
typedef void *HWND;
typedef void *HINSTANCE;
typedef void *HANDLE;

#define LOCK_TYPE std::mutex
#define LOCK(lock) (lock).lock()
#define UNLOCK(lock) (lock).unlock()
#define INIT_LOCK(lock)
#define DESTROY_LOCK(lock)

#define DYNLIB_HANDLE void*
#define DYNLIB_LOAD(libname) dlopen(libname, RTLD_LAZY)
#define DYNLIB_GETSYM(handle, symbol) dlsym(handle, symbol)
#define DYNLIB_FREE(handle) dlclose(handle)
#define DYNLIB_ERROR() dlerror()

#endif

#define MIN(a,b) ((a)<=(b)?(a):(b))
#define MAX(a,b) ((a)>=(b)?(a):(b))

#ifndef MAX_PATH
#define MAX_PATH 4096 // Linux路径最大长度通常为4096字节
#endif

#ifndef BRIDGE6DLL_API
#ifdef _WIN32
#ifdef _USRDLL
#define BRIDGE6DLL_API extern "C" __declspec(dllexport)
#else
#define BRIDGE6DLL_API extern "C" __declspec(dllimport)
#endif
#else
#define BRIDGE6DLL_API extern "C"
#endif
#endif

#define STD_COUT BOOST_LOG_TRIVIAL(info)
#define STD_CERR BOOST_LOG_TRIVIAL(error)
#define STD_ENDL ""

typedef unsigned char BYTE;
typedef int32_t BOOL;
typedef float *PFLOAT;

#define MAX_DOTS (24 * 3600 * 50) // 最大谱图点数，最大支持24小时50HZ数据量。
#define MAX_ANAL_RESULTS 4096     // 最大积分结果数
#define MAX_EVENTS 512            // 最大手动事件数
#define MAX_COMPS 512             // 最大组分数
#define MAX_GROUPS 512            // 最大分组数
#define MAX_SEGMENTS 16           // 最大分段积分数
#define MAX_CALIBRATIONS 512      // 最大校正文件数
#define MAX_CALIB_RESULTS 512     // 最大校正结果数

#ifndef M_PI
#define M_PI 3.1415926
#endif
#define C4 4
#define C8 8
#define C16 16
#define C64 64
#define C256 256
#define C512 512
#define B4 4
#define B8 8
#define B16 16
#define B32 32
#define B64 64
#define B96 96
#define B128 128
#define B256 256
#define B512 512
#define B1024 1024
#define B2048 2048
#define B3072 3072
#define B4096 4096
#define B8192 8192

// 句柄类型
enum E_HANDLE_TYPE
{
    METHOD_HANDLE = 0, // 方法句柄
    ORG_HANDLE = 1,    // 谱图句柄
};

// 谱图文件类型
enum E_SMP_TYPE
{
    BY_SMP = 0, // 试样
    BY_STD = 1, // 标样
    BY_BSL = 2, // 基线
    BY_MDY = 3, // 修改谱图
    BY_DAT = 4, // DAT谱图
    BY_RAW = 5, // MR9X谱图

    BY_UVD = 6, // 紫外/可见光谱图

    BY_VSMP = 7, // VOC样气文件
    BY_VSTD = 8, // VOC标气文件
    BY_VBSL = 9, // VOC零气文件

    MAX_SMPTYPE = (BY_BSL + 1), // 最大的样品类型
    MAX_ORGTYPE = (BY_UVD + 1), //(BY_VBSL+1),  //(BY_RAW+1), //最大的谱图文件类型

    BY_UKNSMP = -1, // 未知的样品类型
    BY_UKNORG = -1, // 未知的谱图文件类型
    BY_ANYSMP = -1, // 任何样品类型
    BY_ANYORG = -1, // 任何谱图文件类型
};

// 空白扣除模式
enum E_SUB_TYPE
{
    SUB_NONE = 0,    // 不扣除
    SUB_ON_CONC = 1, // 直接扣除含量
    SUB_ON_RESP = 2, // 扣响应值后算含量
};

// 变宽模式
enum E_PKWD_MODE
{
    WD_FIXED = 0,   // 固定不变
    WD_TDOUBLE = 1, // 倍宽
    WD_AUTO = 2,    // 自适应
};

// 拖尾峰检测模式
enum E_TAIL_MODE
{
    TAIL_0 = 0, // 不检测拖尾峰
    TAIL_1 = 1, // 强拖尾检测
    TAIL_2 = 2, // 弱拖尾检测
};

// 定量基准
enum E_BASEDON
{
    ON_AREA = 0,   // 面积
    ON_HEIGHT = 1, // 峰高
};

// 定量方法
enum E_QUANTBY
{
    BY_NONE = -1,
    BY_NORMAL = 0,   // 归一化
    BY_S_FACT = 1,   // 修正归一
    BY_INT_STD = 2,  // 内标法
    BY_EXT_STD = 3,  // 外标法
    BY_EXPAND = 4,   // 指数法
    BY_ISTD_PER = 5, // 内标归一
    BY_ESTD_PER = 6, // 外标归一
};

enum E_QUALITBY // 定性模式
{
    BY_BAND = 0,   // 时间带
    BY_WINDOW = 1, // 时间窗
    BY_SERIAL = 2, // 顺序法
};

// 组分类型
enum E_COMP_TYPE
{
    ID_NORMAL = 0,     // 常规组分(Ordnr, ordinary)
    ID_ISTD = 1,       // 内标组分
    ID_REFER = 2,      // 参考组分(Refer)
    ID_SATUR = 3,      // 饱和组分(其百分含量可用100%减去其余组分的百分含量总和)
    ID_OUTER = 4,      // 外部组分(其含量由其它方法确定, 或来自其它谱图分析结果)
    ID_MIXER = 5,      // 混合组分(指多个组分的混合峰, 可在二维柱上进一步分离)
    ID_RISTD = 6,      // 内标参考组分
    ID_CONT_GROUP = 7, // 连续组名
    MAX_ID_TYPE,
};

// 综合结果记录类型
enum E_SYN_TYPE
{
    ITEM_NONE = -1,
    ITEM_COMPOUND = 0,   // 单一组分
    ITEM_CONT_GROUP = 1, // 连续组
    ITEM_DISC_GROUP = 2, // 间断组
    ITEM_SUM_OF_UKS = 3, // 未知峰合计
    ITEM_OUTER_COMP = 4, // 外部组分
    ITEM_PRIME_COMP = 5, // 主要组成
    MAX_SYN_ITEM_TYPE,
};

// 积分事件
enum TICKMARK
{                        // 峰辨识标志
    NO_TICK = 0,         // 无标志
    START_TICK = 1,      // 起点
    VALLEY_TICK = 2,     // 谷点
    APEX_TICK = 4,       // 顶点
    STOP_TICK = 8,       // 止点
    SOL_TICK = 16,       // 溶剂峰
    TAN_START_TICK = 32, // 切线起点
    TAN_STOP_TICK = 64,  // 切线止点
    PIXEL_TICK = 128,    //(Windows环境下无意义)
    DELAY_TICK = 256,    // 死时间事件开始
    UNDELAY_TICK = 512,  // 死时间事件结束
};

// 分析过返回码
enum CODE
{
    ANAL_NOP = 0,     // 空运行
    ANAL_OK = 1,      // 正常运行
    ANAL_STOP = 2,    // 停止运行
    ANAL_TEST = 3,    // 自动测试出两个重要的峰辨识参数：“最小峰宽”和“噪声阈值”
    ANAL_ERROR = 4,   // 运行过程出错
    ANAL_PEAKEND = 5, // 峰组结束
};

// 手动事件标志
enum EVENT
{
    PEAK_START = 0,          // 调整起始点
    PEAK_END = 1,            // 调整结束点
    PEAK_MOVE_SPLIT = 2,     // 移动分割线
    PEAK_ADD_SPLIT = 3,      // 增加分割线
    PEAK_DEL_SPLIT = 4,      // 删除分割线
    PEAK_ADD_ONLYONE = 5,    // 增加单一峰
    PEAK_DELETE = 6,         // 删除峰
    BASE_VALLEY = 7,         // 谷谷基线
    BASE_TOGETHER = 8,       // 强制垂切(峰合并)
    BASE_TAIL_TANGENT = 9,   // 强制拖尾(后切线切割)
    BASE_FRONT_TANGENT = 10, // 前切线切割
    BASE_LOCK = 11,          // 基线锁定      //实时事件
    BASE_NEGATIVE = 12,      // 指定负峰区    //实时事件
    BASE_M_NEGATIVE = 13,    // 指定M型负峰区 //实时事件

    // 以下事件暂不使用：
    BASE_MERGE_UPMOST = 14, // 并入极高峰
    BASE_XXX = 15,          //(保留)
    BASE_FORW_HORI = 16,    // 向前水平基线
    BASE_BACK_HORI = 17,    // 向后水平基线

    PARA_WIDTH = 18, // 调整峰宽参数
    PARA_NOISE = 19, // 调整噪声参数
    PARA_DRIFT = 20, // 调整漂移参数

    // 实时事件的后处理引用:
    BASE_TOGETHER_ = 32, // 强制垂切(峰合并)		//后处理事件
    BASE_TAIL_TANGENT_,  // 强制拖尾(后切线切割)	//后处理事件
    BASE_NEGATIVE_,      // 指定负峰区	//后处理事件(尚未实现)
    BASE_M_NEGATIVE_,    // 指定M型负峰区	//后处理事件(尚未实现)
    BASE_MERGE_UPMOST_,  // 并入最高峰	//后处理事件(尚未实现)

    // 无事件
    NOEVENT = -1
};

// 版本
enum E_VERSION
{
    _CHS_ = 0x00000804, // 中文
    _ZHH_ = 0x00000C04, // 中文(香港)
    _ZHM_ = 0x00001404, // 中文(澳门)
    _CHT_ = 0x00000404, // 中文(台湾)
    _ZHI_ = 0x00001004, // 中文(新加坡)
    _ENU_ = 0x00000409, // 英文(美国)
    _ENG_ = 0x00000809, // 英文(英国)
};

// 手动事件参数
union TPRGPARA
{
    float f;
    int32_t n;
    BOOL b;
};

// 自动峰参数学习池
struct AUTOPOOL
{
    int32_t *buf; // 数据缓冲区(为一循环队列)
    int32_t len;  // 缓冲区长
    int32_t cnt;  // 队列结束指针(开始指针总是为0)
    int32_t ovr;  // 结束指针是否已调头过

#ifdef _USRDLL
    AUTOPOOL() : buf(nullptr), len(0), cnt(0), ovr(0) {}
#endif
};

// 自动参数
struct AUTOPARA
{
    float pkWidth;   // 最小峰宽(min)
    int32_t pkNoise; // 噪声阈值(uV)
    float pkDrift;   // 基线漂移(uV/sec)

#ifdef _USRDLL
    AUTOPARA() : pkWidth(0), pkNoise(0), pkDrift(0) {}
#endif
};

// 标样用量
struct TDLLMETRIC
{
    double enrich;      // 浓缩因子(无单位)
    double amount;      // 样品量(mol,ml,ul,g,mg)
    double dilution;    // 稀释量(ml)
    double injVolume;   // 进样量(ul)
    BOOL byCalib;       // 是否为标样
    int32_t concFactor; // 组分浓度(含量)单位因子[2(100:%,mg%ml),6(10^6:ppm),9(10^9:ppb),12(10^12:ppt)]
    int32_t amtK;       // 样品量单位因子[-1(mg),1000(ml),%(0),-1000(g),ul(-1)]
    int32_t istdK;      // 内标量单位因子
    float columnLength; // 柱长(单位：米)
    float deadTime;     // 死时间(min)

#ifdef _USRDLL
    TDLLMETRIC() : enrich(1.0), amount(0.0), dilution(0.0), injVolume(1.0), byCalib(FALSE), concFactor(0x10000), amtK(0x00010000), istdK(0), columnLength((float)0.0), deadTime((float)0.0) {}
#endif
};

// 品控因子
struct TUkPkFactor
{
    int32_t type; // 0--计零, 1--手工输入, x--组分索引+2
    float f0;
    float f1;
    float f2;
    float f3;
    float cLower; // 品控下限
    float cUpper; // 品控上限

#ifdef _USRDLL
    TUkPkFactor() : type(0), f0(0), f1(0), f2(0), f3(0), cLower(0), cUpper(0) {}
#endif
};

// 积分参数
struct TIPara
{
    float pkWidth;       // 最小峰宽(min)
    int32_t pkNoise;     // 噪声阈值(uV)
    float pkDrift;       // 漂移(uV/sec)
    float testPkWidth;   // 自动测试出的峰宽值(min)
    int32_t testPkNoise; // 自动测试出的噪声值(uV)
    float testPkDrift;   // 自动测试出的漂移值(uV/min)
    float initTime;      // 起始积分时间(min)
    float stopTime;      // 自动停止时间(min)
    int32_t minArea;     // 最小峰面积(uV.s)
    int32_t minHeight;   // 最小峰高(uV)
    E_PKWD_MODE wdMode;  // 变宽模式
    float tdouble;       // 倍宽时间(min)
    int32_t tailMode;    // 拖尾峰检测模式
    BOOL autoNegative;   // 是否自动检测负峰
    BOOL shouldSens;     // 是否肩峰敏感
    BOOL tprgUsed;       // 是否使用时间表
    int32_t width;       // 滤波宽度(count) [用于算法内部,界面上不必体现]
    float slope;         // 斜率(uV/count)  [用于算法内部,界面上不必体现]
    float drift;         // 漂移(uV/count)  [用于算法内部,界面上不必体现]
    char nop[B32];

#ifdef _USRDLL
    // 构造函数
    TIPara() : pkWidth(0.0f), pkNoise(0), pkDrift(0.0f), testPkWidth(0.0f), testPkNoise(0),
               testPkDrift(0.0f), initTime(0.0f), stopTime(0.0f), minArea(0), minHeight(0),
               wdMode(WD_AUTO), tdouble(0.0f), tailMode(TAIL_0), autoNegative(0), shouldSens(0),
               tprgUsed(0), width(0), slope(0.0f), drift(0.0f)
    {
        std::fill_n(nop, sizeof(nop), '\0');
    };
#endif
};

// 自动参数
struct AUTOIPARA
{
    int32_t width; // 最小峰宽(min)
    float noise;   // 噪声阈值(uV)
    float drift;   // 基线漂移(uV/count)

#ifdef _USRDLL
    AUTOIPARA() : width(0), noise(0), drift(0)
    {
    }
#endif
};

struct TEPara // 计算参数
{
    E_BASEDON based;   // 定量基准
    E_QUANTBY quantBy; // 定量方法
    BOOL grouped;      // 是否分组

#ifdef _USRDLL
    // 构造函数
    TEPara() : based(ON_AREA), quantBy(BY_EXT_STD), grouped(0) {}
#endif
};

// 应用程序接口设置
struct TAPPSetting
{
    char Version[16]; // 版本号
    DWORD LanguageID; // 语言ID
    BYTE Reserves[1024 - (16 + 4)];
};

#endif